package com.alibaba.csp.sentinel.dashboard.datasource.entity;

import org.influxdb.annotation.Column;
import org.influxdb.annotation.Measurement;

import java.time.Instant;

@Measurement(name = "sentinel_metric")
public class InfluxdbMetricEntity {
    @Column(name = TIME)
    private Instant time;
    @Column(name = GMT_CREATE)
    private Long gmtCreate;
    @Column(name = GMT_MODIFIED)
    private Long gmtModified;
    @Column(name = APP, tag = true)
    private String app;
    @Column(name = INSTANCE, tag = true)
    private String instance;

    @Column(name = RESOURCE, tag = true)
    private String resource;
    @Column(name = TIMESTAMP)
    private Long timestamp;
    @Column(name = PASS_QPS)
    private Long passQps;
    @Column(name = SUCCESS_QPS)
    private Long successQps;
    @Column(name = BLOCK_QPS)
    private Long blockQps;
    @Column(name = EXCEPTION_QPS)
    private Long exceptionQps;

    @Column(name = RT)
    private double rt;

    /**
     * 本次聚合的总条数
     */
    @Column(name = COUNT)
    private int count;
    @Column(name = RESOURCE_CODE)
    private int resourceCode;

    public synchronized void addPassQps(Long passQps) {
        this.passQps += passQps;
    }

    public synchronized void addBlockQps(Long blockQps) {
        this.blockQps += blockQps;
    }

    public synchronized void addExceptionQps(Long exceptionQps) {
        this.exceptionQps += exceptionQps;
    }

    public synchronized void addCount(int count) {
        this.count += count;
    }

    public synchronized void addRtAndSuccessQps(double avgRt, Long successQps) {
        this.rt += avgRt * successQps;
        this.successQps += successQps;
    }

    /**
     * {@link #rt} = {@code avgRt * successQps}
     *
     * @param avgRt      average rt of {@code successQps}
     * @param successQps
     */
    public synchronized void setRtAndSuccessQps(double avgRt, Long successQps) {
        this.rt = avgRt * successQps;
        this.successQps = successQps;
    }

    public Long getGmtCreate() {
        return gmtCreate;
    }

    public void setGmtCreate(Long gmtCreate) {
        this.gmtCreate = gmtCreate;
    }

    public Long getGmtModified() {
        return gmtModified;
    }

    public void setGmtModified(Long gmtModified) {
        this.gmtModified = gmtModified;
    }

    public Long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(Long timestamp) {
        this.timestamp = timestamp;
    }

    public String getResource() {
        return resource;
    }

    public void setResource(String resource) {
        this.resource = resource;
        this.resourceCode = resource.hashCode();
    }

    public Long getPassQps() {
        return passQps;
    }

    public void setPassQps(Long passQps) {
        this.passQps = passQps;
    }

    public Long getBlockQps() {
        return blockQps;
    }

    public void setBlockQps(Long blockQps) {
        this.blockQps = blockQps;
    }

    public Long getExceptionQps() {
        return exceptionQps;
    }

    public void setExceptionQps(Long exceptionQps) {
        this.exceptionQps = exceptionQps;
    }

    public double getRt() {
        return rt;
    }

    public void setRt(double rt) {
        this.rt = rt;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getResourceCode() {
        return resourceCode;
    }

    public Long getSuccessQps() {
        return successQps;
    }

    public void setSuccessQps(Long successQps) {
        this.successQps = successQps;
    }

    public Instant getTime() {
        return time;
    }

    public void setTime(Instant time) {
        this.time = time;
    }

    public String getApp() {
        return app;
    }

    public void setApp(String app) {
        this.app = app;
    }

    public String getInstance() {
        return instance;
    }

    public void setInstance(String instance) {
        this.instance = instance;
    }

    @Override
    public String toString() {
        return "InfluxdbMetricEntity{" +
                "time=" + time +
                ", gmtCreate=" + gmtCreate +
                ", gmtModified=" + gmtModified +
                ", app='" + app + '\'' +
                ", instance='" + instance + '\'' +
                ", resource='" + resource + '\'' +
                ", timestamp=" + timestamp +
                ", passQps=" + passQps +
                ", successQps=" + successQps +
                ", blockQps=" + blockQps +
                ", exceptionQps=" + exceptionQps +
                ", rt=" + rt +
                ", count=" + count +
                ", resourceCode=" + resourceCode +
                '}';
    }

    public static final String TIME = "time";
    public static final String GMT_CREATE = "gmtCreate";
    public static final String GMT_MODIFIED = "gmtModified";
    public static final String APP = "app";
    public static final String INSTANCE = "instance";
    public static final String RESOURCE = "resource";
    public static final String TIMESTAMP = "timestamp";
    public static final String PASS_QPS = "passQps";
    public static final String SUCCESS_QPS = "successQps";
    public static final String BLOCK_QPS = "blockQps";
    public static final String EXCEPTION_QPS = "exceptionQps";
    public static final String RT = "rt";
    public static final String COUNT = "count";
    public static final String RESOURCE_CODE = "resourceCode";
}
